/**
 * Copyright (c) 2018 人人开源 All rights reserved.
 * <p>
 * https://www.renren.io
 * <p>
 * 版权所有，侵权必究！
 */

package com.dkha.server.system.modules.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dkha.common.enums.YNEnums;
import com.dkha.common.exception.DkException;
import com.dkha.common.util.UtilValidate;
import com.dkha.server.modules.entities.FaceCameraEntity;
import com.dkha.server.services.FaceCameraService;
import com.dkha.server.services.IControlBayonetMidService;
import com.dkha.server.system.common.exception.ErrorCode;
import com.dkha.server.system.common.exception.RenException;
import com.dkha.server.system.common.service.impl.BaseServiceImpl;
import com.dkha.server.system.common.utils.ConvertUtils;
import com.dkha.server.system.common.utils.TreeUtils;
import com.dkha.server.system.modules.security.user.SecurityUser;
import com.dkha.server.system.modules.sys.dao.SysRegionDao;
import com.dkha.server.system.modules.sys.dto.SysDictDTO;
import com.dkha.server.system.modules.sys.dto.SysRegionDTO;
import com.dkha.server.system.modules.sys.dto.region.Region;
import com.dkha.server.system.modules.sys.dto.region.RegionCity;
import com.dkha.server.system.modules.sys.dto.region.RegionProvince;
import com.dkha.server.system.modules.sys.entity.SysRegionEntity;
import com.dkha.server.system.modules.sys.enums.RegionLeafEnum;
import com.dkha.server.system.modules.sys.enums.RegionLevelEnum;
import com.dkha.server.system.modules.sys.enums.RegionTopEnum;
import com.dkha.server.system.modules.sys.service.SysRegionService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;


@Service
public class SysRegionServiceImpl extends BaseServiceImpl<SysRegionDao, SysRegionEntity> implements SysRegionService {

    @Autowired
    private IControlBayonetMidService controlBayonetMidServiceImpl;

    @Autowired
    private FaceCameraService faceCameraServiceImpl;

    @Override
    public List<SysRegionDTO> list(Map<String, Object> params) {
        String pid = (String) params.get("pid");

        if (UtilValidate.isEmpty(pid)) {
            //查询一级
            params.put("treeLevel", RegionLevelEnum.ONE.value());
        }
        //查询列表
        List<SysRegionEntity> entityList = baseDao.getList(params);

        List<SysRegionDTO> dtoList = new ArrayList<>(entityList.size());
        for (SysRegionEntity entity : entityList) {
            SysRegionDTO dto = new SysRegionDTO();
            BeanUtils.copyProperties(entity, dto);
            dto.setHasChildren(entity.getLeaf() != 1);

            dtoList.add(dto);
        }

        return dtoList;
    }

    @Override
    public List<SysRegionDTO> allList() {
        List<SysRegionEntity> list = baseDao.selectList(new QueryWrapper<>());
        List<SysRegionDTO> dtoList = ConvertUtils.sourceToTarget(list, SysRegionDTO.class);
        return TreeUtils.build(dtoList);
    }

    @Override
    public List<Map<String, Object>> getTreeList() {
        return baseDao.getTreeList();
    }

    @Override
    public SysRegionDTO get(Long id) {
        SysRegionEntity entity = baseDao.getById(id);

        return ConvertUtils.sourceToTarget(entity, SysRegionDTO.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(SysRegionDTO dto) {
        SysRegionEntity entity = ConvertUtils.sourceToTarget(dto, SysRegionEntity.class);

        //查询上级
        SysRegionEntity parentEntity = baseDao.getById(dto.getPid());
        if (parentEntity == null) {
            entity.setTreeLevel(RegionLevelEnum.ONE.value());
            //查询当前有几个第一级区域
            List<SysRegionEntity> firstLevel = baseDao.selectList(new QueryWrapper<SysRegionEntity>().eq("tree_level", 1));
            //当前存在多个一级区域
            if (firstLevel != null && firstLevel.size() > 0) {
                entity.setPid(Long.valueOf(firstLevel.size()));
            }
        } else {

            entity.setTreeLevel(parentEntity.getTreeLevel() + 1);
            //上级存在，且为叶子节点，需要修改为非叶子节点
            if (parentEntity.getLeaf() == RegionLeafEnum.YES.value()) {
                parentEntity.setLeaf(RegionLeafEnum.NO.value());
                baseDao.updateById(parentEntity);
            }
        }
        entity.setCreator(SecurityUser.getUser() == null ? null : SecurityUser.getUser().getId());
        entity.setCreateDate(new Date());
        entity.setUpdater(SecurityUser.getUser() == null ? null : SecurityUser.getUser().getId());
        entity.setUpdateDate(new Date());
        //新增都是叶子节点
        entity.setLeaf(RegionLeafEnum.YES.value());
        insert(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(SysRegionDTO dto) {
        SysRegionEntity entity = ConvertUtils.sourceToTarget(dto, SysRegionEntity.class);

        //上级不能为自身
        if (entity.getId().equals(entity.getPid())) {
            throw new RenException(ErrorCode.SUPERIOR_REGION_ERROR);
        }

        //查询上级
        SysRegionEntity parentEntity = baseDao.getById(dto.getPid());
        if (parentEntity == null) {
            entity.setTreeLevel(RegionLevelEnum.ONE.value());
        } else {
            entity.setTreeLevel(parentEntity.getTreeLevel() + 1);
            //上级存在，且为叶子节点，需要修改为非叶子节点
            if (parentEntity.getLeaf() == RegionLeafEnum.YES.value()) {
                parentEntity.setLeaf(RegionLeafEnum.NO.value());
                baseDao.updateById(parentEntity);
            }
        }

        //查询下级
        int subCount = baseDao.getCountByPid(dto.getId());
        if (subCount == 0) {
            entity.setLeaf(RegionLeafEnum.YES.value());
        } else {
            entity.setLeaf(RegionLeafEnum.NO.value());
        }
        entity.setUpdater(SecurityUser.getUser() == null ? null : SecurityUser.getUser().getId());
        entity.setUpdateDate(new Date());
        updateById(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id) {
        //判断是否为顶级区域
        SysRegionEntity dao = baseDao.getById(id);
//        if (dao.getPid() == RegionTopEnum.FATHER.value()) {
//            throw new DkException("该区域为顶级区域、不允许删除");
//        }
        //判断区域下是否有摄像头
        List<Map<String, Object>> list = faceCameraServiceImpl.listMaps(new QueryWrapper<FaceCameraEntity>().eq("is_valid", YNEnums.YES.code).like("camera_region_firstlevel", "%" + id + "%"));
        if (UtilValidate.isNotEmpty(list)) {
            throw new DkException("该区域下存在布控任务或者摄像头，不允许删除");
        }
        baseDao.deleteById(id);
        //判断父级是否还有子级，若无修改上级为叶子节点
        if (baseDao.getCountByPid(dao.getPid()) == 0) {
            SysRegionEntity fatherDao = baseDao.getById(dao.getPid());
            if (UtilValidate.isNotEmpty(fatherDao)) {
                fatherDao.setLeaf(RegionLeafEnum.YES.value());
                baseDao.updateById(fatherDao);
            }

        }

    }

    @Override
    public int getCountByPid(Long pid) {
        return baseDao.getCountByPid(pid);
    }

    @Override
    public List<SysRegionEntity> getRegionByLevel(Integer level) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("tree_level", level);
        List<SysRegionEntity> list = baseDao.selectList(queryWrapper);
        return list;
    }

    @Override
    public List<RegionProvince> getRegion(boolean threeLevel) {
        List<SysRegionEntity> provinceList = baseDao.getListByLevel(RegionLevelEnum.ONE.value());
        List<SysRegionEntity> cityList = baseDao.getListByLevel(RegionLevelEnum.TWO.value());

        List<RegionProvince> provinces = ConvertUtils.sourceToTarget(provinceList, RegionProvince.class);
        List<RegionCity> cities = ConvertUtils.sourceToTarget(cityList, RegionCity.class);

        for (RegionCity city : cities) {
            for (RegionProvince province : provinces) {
                if (city.getPid().equals(province.getId())) {
                    province.getCities().add(city);
                }
            }
        }

        //无需显示3级区县
        if (!threeLevel) {
            return provinces;
        }

        List<SysRegionEntity> countyList = baseDao.getListByLevel(RegionLevelEnum.THREE.value());
        List<Region> counties = ConvertUtils.sourceToTarget(countyList, Region.class);
        for (Region county : counties) {
            for (RegionCity city : cities) {
                if (county.getPid().equals(city.getId())) {
                    city.getCounties().add(county);
                }
            }
        }

        return provinces;
    }
}
